package com.cskaoyan.shiro;


import com.cskaoyan.bean.entity.Admin;
import com.cskaoyan.bean.entity.AdminExample;
import com.cskaoyan.bean.entity.User;
import com.cskaoyan.bean.entity.UserExample;
import com.cskaoyan.mapper.AdminMapper;
import com.cskaoyan.mapper.UserMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义一个CustomRealm域：根据认证信息和授权信息中的一部分获取另一份信息（比如：通过用户名，获取对应的密码信息）
 * 认证模块：
 * 授权模块：
 */

@Primary
@Component
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    AdminMapper adminMapper;


    //建议把获得认证信息的方法写在前面
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //通过AuthenticationToken实例对象获取认证信息token
        //参数AuthenticationToken 来源于 subject.login的时候携带的参数
        MallToken token = (MallToken) authenticationToken;

        String username = token.getUsername();

        // 后端管理员登录
        //根据username查询到正确的密码 → 通常维护在数据库里
        AdminExample example = new AdminExample();
        example.createCriteria().andUsernameEqualTo(username);
        // 管理员
        List<Admin> admins = adminMapper.selectByExample(example);
        if (admins == null || admins.size() == 0) {
            return null;
        }
        Admin admin = admins.get(0);     //获取一个admin
        String credential = admin.getPassword();//数据库中维护的当前用户名的password
        //第一个参数：Principal
        //第二个参数：credentials
        //第三个参数：当前realm的名称
        return new SimpleAuthenticationInfo(admin,credential,this.getName());  //返回一个简单的认证信息

    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获得用户信息principal → 上面返回认证信息的第一个参数里维护了用户信息
        Admin primaryPrincipal = (Admin) principalCollection.getPrimaryPrincipal();
        Integer id = primaryPrincipal.getId();
        //根据用户信息获得他所有的权限信息 → 数据库的查询
        List<String> permissions = queryFromDb(id);//这个方法大家自己来写
        //给授权信息 增加上该用户所拥有的权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    private List<String> queryFromDb(Integer id) {
        ArrayList<String> strings = new ArrayList<>();
        strings.add("songge:user");
        strings.add("admin:user:list");
        return strings;
    }
}
